package com.cxb.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.location.GpsSatellite;
import android.location.GpsStatus;
import android.location.GpsStatus.Listener;
import android.location.GpsStatus.NmeaListener;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import java.util.Iterator;

import com.cxb.utils.CommonUtils;

/**
 * 
 * 描述：用于显示GPS信号 陈伟斌 2014-3-7
 */
public class GpsInfoView extends View implements NmeaListener {
	int MAX_USING_STAR = 13;
	int MAX_CNCOUNT = 60;
	int TEXT_HEIGHT = 16;

	public int nSvInUse = 0;
	public int nSvCount = 0;
	public boolean bFixed = false;
	public Location stLocation = new Location("gps");

	int nStarRadius = 4;
	int nEarthRadius = 25;
	Rect rcEarth = new Rect(182, 52, 282, 152);
	Rect rcSignal = new Rect(10, 154, 10 + 25 * this.MAX_USING_STAR, 228);
	LocationManager loctionManager = null;
	public GpsStatus gpsStatus = null;

	private LocationListener locationListener = new LocationListener() {
		public void onLocationChanged(Location location) {
			if (location == null)
				return;
			GpsInfoView.this.stLocation = location;
			if (location.getLatitude() != 0 || location.getLongitude() != 0) {
				GpsInfoView.this.bFixed = true;
			}
		}

		public void onProviderDisabled(String provider) {
			Log.d("onProviderDisabled", provider);
		}

		public void onProviderEnabled(String provider) {
		}

		public void onStatusChanged(String provider, int status, Bundle extras) {
			if (status == 2)
				GpsInfoView.this.bFixed = true;
			else
				GpsInfoView.this.bFixed = false;
		}
	};

	GpsStatus.Listener statusListener = new GpsStatus.Listener() {
		public void onGpsStatusChanged(int event) {
			switch (event) {
			case 4:
				GpsInfoView.this.gpsStatus = GpsInfoView.this.loctionManager
						.getGpsStatus(null);
				GpsInfoView.this.invalidate();

				break;
			case 3:
				GpsInfoView.this.bFixed = true;
				break;
			case 1:
				GpsInfoView.this.bFixed = false;
				break;
			case 2:
				GpsInfoView.this.bFixed = false;
			}
		}
	};

	public GpsInfoView(Context context) {
		super(context);

		this.loctionManager = ((LocationManager) context
				.getSystemService("location"));
		try {
			this.loctionManager.requestLocationUpdates("gps", 1000L, 0.0F,
					this.locationListener);
			this.loctionManager.addGpsStatusListener(this.statusListener);
			this.loctionManager.addNmeaListener(this);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	protected void finalize() throws Throwable {
		this.loctionManager.removeGpsStatusListener(this.statusListener);
		this.loctionManager.removeUpdates(this.locationListener);
		super.finalize();
	}

	protected void onDraw(Canvas canvas) {
		DrawStarOnEarth(canvas);
		DrawStarSignal(canvas);
	}

	void DrawStarOnEarth(Canvas canvas) {
		if (this.gpsStatus == null) {
			return;
		}
		Paint paint = new Paint();
		paint.setAntiAlias(true);
		paint.setTextAlign(Paint.Align.CENTER);
		paint.setTextSize(this.nStarRadius * 1.5F);

		Rect rcStar = new Rect();
		Iterator satellites = this.gpsStatus.getSatellites().iterator();
		while (satellites.hasNext()) {
			GpsSatellite satellite = (GpsSatellite) satellites.next();
			double dbRadius = (90.0F - satellite.getElevation())
					* this.nEarthRadius / 90.0F;
			double angle = -(satellite.getAzimuth() - 90.0F) * 3.1415926D / 180.0D;

			rcStar.left = (this.rcEarth.left - this.nStarRadius
					+ this.nEarthRadius + (int) (dbRadius * Math.cos(angle)));
			rcStar.top = (this.rcEarth.top - this.nStarRadius
					+ this.nEarthRadius - (int) (dbRadius * Math.sin(angle)));

			rcStar.right = (rcStar.left + (this.nStarRadius << 1));
			rcStar.bottom = (rcStar.top + (this.nStarRadius << 1));
//33b5e6
			if (satellite.usedInFix()) {
				paint.setColor(Color.rgb(0x33, 0xb5	, 0xe6));
			} else {
				paint.setColor(Color.rgb(0x95, 0xF5, 0xe6));
			}

			paint.setStyle(Paint.Style.FILL);
			canvas.drawCircle((rcStar.left + rcStar.right) / 2,
					(rcStar.top + rcStar.bottom) / 2, 4f, paint);

//			paint.setColor(-16777216);
//			paint.setStyle(Paint.Style.STROKE);
//			canvas.drawCircle((rcStar.left + rcStar.right) / 2,
//					(rcStar.top + rcStar.bottom) / 2, this.nStarRadius, paint);

//			canvas.drawText(Integer.toString(satellite.getPrn()),
//					(rcStar.left + rcStar.right) / 2,
//					(rcStar.top + rcStar.bottom) / 2 + this.nStarRadius / 2,
//					paint);
		}
	}

	void DrawStarSignal(Canvas canvas) {
		if (this.gpsStatus == null) {
			Paint p = new Paint();
			p.setColor(Color.TRANSPARENT);
			canvas.drawRect(this.rcSignal, p);
			return;
		}

		Paint paint = new Paint();
		paint.setAntiAlias(true);
		paint.setTextAlign(Paint.Align.CENTER);
		paint.setTextSize(this.nStarRadius * 1.5F);

		Rect rcBar = new Rect();
		Rect rcCN = new Rect();
		Rect rcNum = new Rect();

		int nsvcount = 0;
		int nsvinuse = 0;
		Iterator satellites = this.gpsStatus.getSatellites().iterator();
		while (satellites.hasNext()) {
			GpsSatellite satellite = (GpsSatellite) satellites.next();

			rcBar.left = (this.rcSignal.left + nsvcount
					* (this.rcSignal.right - this.rcSignal.left)
					/ this.MAX_USING_STAR) + 15;
			rcBar.top = (this.rcSignal.top + (this.MAX_CNCOUNT - (int) satellite
					.getSnr())
					* (this.rcSignal.bottom - this.rcSignal.top - this.TEXT_HEIGHT)
					/ this.MAX_CNCOUNT);

			rcBar.right = (rcBar.left
					+ (this.rcSignal.right - this.rcSignal.left)
					/ this.MAX_USING_STAR - 2) - 20;
			rcBar.bottom = (this.rcSignal.bottom - this.TEXT_HEIGHT);

			if (satellite.usedInFix()) {
				++nsvinuse;
				paint.setColor(Color.rgb(0x80, 0x80, 0x80));
			} else {
				paint.setColor(Color.rgb(0xA0, 0xA0, 0xA0));
			}

			if (satellite.getSnr() > 0.0F) {
				canvas.drawRect(rcBar, paint);

				paint.setColor(Color.rgb(49, 211, 57));
				rcCN.set(rcBar.left, this.rcSignal.top, rcBar.right - 10,
						this.rcSignal.top + this.TEXT_HEIGHT);
				canvas.drawText(Integer.toString((int) satellite.getSnr()),
						(rcCN.left + rcCN.right) / 2 + 5,
						(rcCN.top + rcCN.bottom) / 2, paint);
			}

			paint.setColor(Color.rgb(51, 153, 255));
			rcNum.set(rcBar.left, this.rcSignal.bottom - this.TEXT_HEIGHT,
					rcBar.right, this.rcSignal.bottom);
			canvas.drawText(Integer.toString(satellite.getPrn()),
					(rcNum.left + rcNum.right) / 2, (rcNum.top + rcNum.bottom)
							/ 2 + this.TEXT_HEIGHT - 8, paint);

			++nsvcount;
		}
		this.nSvInUse = nsvinuse;
		this.nSvCount = nsvcount;
	}

	public void MoveEarth(int x, int y, int nWidth, int nHeight) {
		this.rcEarth.left = x;
		this.rcEarth.top = y;
		this.rcEarth.right = (this.rcEarth.left + nWidth);
		this.rcEarth.bottom = (this.rcEarth.top + nHeight);

		this.nEarthRadius = (this.rcEarth.right - this.rcEarth.left >> 1);
		invalidate();
	}

	public void MoveSignal(int x, int y, int nWidth, int nHeight) {
		this.rcSignal.left = x;
		this.rcSignal.top = y;
		this.rcSignal.right = (this.rcSignal.left + nWidth);
		this.rcSignal.bottom = (this.rcSignal.top + nHeight);
		invalidate();
	}

	public void SetStarRadius(int radius) {
		this.nStarRadius = radius;
		invalidate();
	}

	public void ColdStart() {
		this.loctionManager.removeGpsStatusListener(this.statusListener);
		this.loctionManager.removeUpdates(this.locationListener);
		this.loctionManager.sendExtraCommand(LocationManager.GPS_PROVIDER,
				"delete_aiding_data", null);

		try {
			Thread.sleep(1000L);
		} catch (Exception e) {
			e.printStackTrace();
		}

		this.nSvInUse = 0;
		this.nSvCount = 0;
		this.bFixed = false;
		this.stLocation.setLatitude(0.0D);
		this.stLocation.setLongitude(0.0D);
		this.stLocation.setTime(0L);
		this.stLocation.setSpeed(0.0F);
		this.gpsStatus = null;
		this.invalidate();

		try {
			this.loctionManager.requestLocationUpdates("gps", 1000L, 0.0F,
					this.locationListener);
			this.loctionManager.addGpsStatusListener(this.statusListener);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void reInitGpsView() {
		this.nSvInUse = 0;
		this.nSvCount = 0;
		this.bFixed = false;
		this.stLocation.setLatitude(0.0D);
		this.stLocation.setLongitude(0.0D);
		this.stLocation.setTime(0L);
		this.stLocation.setSpeed(0.0F);
		this.loctionManager.requestLocationUpdates("gps", 1000L, 0.0F,
				this.locationListener);
		this.loctionManager.addGpsStatusListener(this.statusListener);
		this.invalidate();
	}

	int locationMode;
	float PDOP, HDOP, VDOP;


	public float getPDOP() {
		return Float.parseFloat(CommonUtils.roundTwo(PDOP));
	}
	public float getHDOP() {
		return Float.parseFloat(CommonUtils.roundTwo(HDOP));
	}
	public float getVDOP() {
		return Float.parseFloat(CommonUtils.roundTwo(VDOP));
	}
	public String getMode() {
		return locationMode+"D";
	}

	@Override
	public void onNmeaReceived(long timestamp, String nmea) {
		try {

			if (nmea != null && nmea.startsWith("$GPGSA")) {
				String[] str = nmea.split(",");
				locationMode = Integer.parseInt(str[2]);
				PDOP = Float.parseFloat(str[str.length - 3]);
				HDOP = Float.parseFloat(str[str.length - 2]);
				String vdopStr = str[str.length - 1];
				VDOP = Float.parseFloat(vdopStr.substring(0,
						vdopStr.lastIndexOf("*")));
				System.out.println();
			}
			// this.nema = nmea;
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}